package profile;

/**
 * This class represents a peak or dip in a profile
 * 
 */
public class Dip {
    
    public int start;
    public int end;
    
    private double[] arr;
    
    private double min;
    private double sum;
    public double amplitude;
    
    Dip(int start, int end, double[] arr) {
        this.start = start;
        this.end = end;
        this.arr = arr;
        
        setMin(arr);
    }
    
    /**
     * Sets the min of the peak (actually the dip in our case)
     * 
     * @param arr
     */
    private void setMin(double[] arr) {
        double min = Double.MAX_VALUE;
        for(int i = start; i <= end; i++) {
            if(arr[i] < min) {
                min = arr[i];
            }
        }
        
        this.min = min;
    }
    
    /**
     * Calculates the area under FWHM
     * 
     * @param signalAtFWHM
     * @param mean
     * @return
     */
    public double getAreaUnderFWHM(double signalAtFWHM, double mean) {
        double sum = 0;
        int width = 0;
        for(int i = start; i <= end; i++) {
            if(arr[i] < signalAtFWHM) {
                sum += arr[i];
                width++;
            }
        }
        
        return ((width * mean) - sum);
    }
    
    
    public double getSum() {
        return sum;
    }
    
    public double getMin() {
        return min;
    }
    
    public int getWidthUnderValue(double value) {
    	int width = 0;
    	for(int i = start; i <= end; i++) {
    		if (arr[i] < value) {
    			width++;
    		}
    	}
    	return width;
    }
    
    public double getSummationUnderThreshold(double mean, double threshold) {
    	double sum = 0;
    	for(int i = start; i <= end; i++) {
    		if(arr[i] < threshold) {
    			sum += (mean - arr[i]);
    		}
    	}
    	return sum;
    }

	public double getDipAreaInDbElements(long dRange, long numElts, double mean, double threshold, double profileWidth) {
		double area = 0;
		for(int i = start; i <= end; i++) {
			if (arr[i] < threshold) {
				area += ((double)dRange/(double)256) * (mean - arr[i]) * ((double) numElts / (double)profileWidth);
			}
		}
		
		return area;
	}
	
	public int getWidth() {
	    return (end - start);
	}
}
